#include "res/shaders/BlendMode.frag"

float spread = 1.4;

uniform float num1;
uniform float num2;
uniform float num3;

uniform sampler2D skinExMask;
uniform sampler2D lutTexture;

vec3 rgb2hsv(vec3 c) {
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
    vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    vec3 hsv = vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
    return hsv;
}

vec4 lut(vec4 color, sampler2D lutSampler, float intensity) {
    float blueColor = color.b * 63.0;
    vec2 quad1 = vec2(0.0,0.0);
    quad1.y = floor(floor(blueColor) / 8.0);
    quad1.x = floor(blueColor) - (quad1.y * 8.0);

    vec2 quad2;
    quad2.y = floor(ceil(blueColor) / 8.0);
    quad2.x = ceil(blueColor) - (quad2.y * 8.0);

    vec2 texPos1;
    texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);
    texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);

    vec2 texPos2;
    texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);
    texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);

    texPos1.y = 1.0 - texPos1.y;
    texPos2.y = 1.0 - texPos2.y;

    vec4 newColor1 = texture2D(lutSampler, texPos1);
    vec4 newColor2 = texture2D(lutSampler, texPos2);

    vec4 newColor = mix(newColor1, newColor2, fract(blueColor));
    return mix(color, vec4(newColor.rgb, color.w), intensity);
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{    
    vec2 uv = (fragCoord.xy / iResolution.xy);
    
    vec4 cameraColor = texture2D(iChannel0, uv);
    vec4 blendHair = texture2D(iChannel1, uv);
    vec4 hairMask = texture2D(iChannel2, uv);
    vec4 hairBlurMask = texture2D(iChannel3, uv);
    vec4 skinExMask = texture(skinExMask, uv);


    vec4 sum = hairMask;
    vec2 step = spread / iResolution;
    for(int y = -3; y <= 3; y++){
        for(int x = -3; x <= 3; x++){
          vec4 color = texture(iChannel2, uv + vec2(x, y) * step);
          sum = min(color, sum);
        }
    }
    sum = 1.0 - sum;

    float blurMix = 0.58; // num1
    float segMix = 0.27; // num2

    float hairMaskFloat2 = (1.0 - hairBlurMask.r);
    float hairBlurMaskFloat = (1.0 - hairBlurMask.r);
    hairBlurMaskFloat = max(hairBlurMaskFloat - blurMix, 0.0) / (1.0 - blurMix);

    float mixColor = mix(hairMaskFloat2, hairBlurMaskFloat, segMix);

    mixColor = mix(sum.r, mixColor, skinExMask.r);

    vec4 blurColor = vec4(mixColor, mixColor, mixColor, 0.5);

    if (mixColor > 0.0) {
        vec4 lutColor = lut(cameraColor, lutTexture, 1.0);
        cameraColor = mix(cameraColor, lutColor, mixColor);
    }
    
    fragColor = ^{blendType0}^(cameraColor, vec4(blendHair.rgb, mixColor * blendHair.a), false);
}
